package org.msb.accentis.gui.dialogs;

import static java.awt.GridBagConstraints.CENTER;
import static java.awt.GridBagConstraints.HORIZONTAL;
import static java.awt.GridBagConstraints.NONE;
import static java.awt.GridBagConstraints.SOUTHEAST;

import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Arrays;

import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

import org.msb.accentis.data.DataManagerFactory;
import org.msb.accentis.gui.InsetsConstants;
import org.msb.accentis.gui.Resources;
import org.msb.accentis.gui.swing.ActionResourceDefinition;
import org.msb.accentis.gui.swing.MSBAction;

public class NewDatabaseDialog extends JDialog {

	private JTextField locationField;

	private Action browseAction;

	private JPasswordField passwordField;

	private JPasswordField confirmField;

	private Action okAction;

	private Action cancelAction;

	private ActionListener actionListener;

	private JFileChooser fileChooser;
	
	public NewDatabaseDialog(Frame parent) {
		super(parent, Resources.getInstance().getString("newdatabasedialog.title"), ModalityType.APPLICATION_MODAL);
	}

	@Override
	protected void dialogInit() {
		super.dialogInit();

		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				resetFields();
			}
		});
		
		setContentPane(createContentPane());
		setDefaultCloseOperation(HIDE_ON_CLOSE);
		setSize(400,200);
	}

	protected JComponent createContentPane() {
		JPanel contentPane = new JPanel(new GridBagLayout());
		contentPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

		contentPane.add(new JLabel(Resources.getInstance().getString("newdatabasedialog.location.caption")), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
				CENTER, NONE, InsetsConstants.ZERO_INSETS, 0, 0));
		contentPane.add(getLocationField(), new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, CENTER, HORIZONTAL, InsetsConstants.FIVE_ON_LEFT_INSETS, 0, 0));
		contentPane.add(new JButton(getBrowseAction()), new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, CENTER, NONE, InsetsConstants.FIVE_ON_LEFT_INSETS, 0, 0));

		contentPane.add(new JLabel(Resources.getInstance().getString("newdatabasedialog.password.caption")), new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
				CENTER, NONE, InsetsConstants.FIVE_ON_TOP_INSETS, 0, 0));
		contentPane
				.add(getPasswordField(), new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, CENTER, HORIZONTAL, InsetsConstants.FIVE_ON_TOP_AND_LEFT_INSETS, 0, 0));

		contentPane.add(new JLabel(Resources.getInstance().getString("newdatabasedialog.confirm.caption")), new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0,
				CENTER, NONE, InsetsConstants.FIVE_ON_TOP_INSETS, 0, 0));
		contentPane.add(getConfirmField(), new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0, CENTER, HORIZONTAL, InsetsConstants.FIVE_ON_TOP_AND_LEFT_INSETS, 0, 0));

		JPanel buttonPanel = new JPanel(new GridLayout(1, 2, 5, 0));

		buttonPanel.add(createDefaultButton(getOkAction()));
		buttonPanel.add(new JButton(getCancelAction()));

		contentPane.add(buttonPanel, new GridBagConstraints(0, 3, 3, 1, 0.0, 1.0, SOUTHEAST, NONE, InsetsConstants.FIVE_ON_TOP_INSETS, 0, 0));

		return contentPane;
	}
	
	private JButton createDefaultButton(Action action) {
		JButton button = new JButton(action);
		getRootPane().setDefaultButton(button);
		
		return button;
	}

	protected JTextField getLocationField() {
		if (null == locationField)
			createLocationField();

		return locationField;
	}

	private void createLocationField() {
		locationField = new JTextField();
	}

	protected Action getBrowseAction() {
		if (null == browseAction)
			createBrowseAction();

		return browseAction;
	}

	private void createBrowseAction() {
		browseAction = new MSBAction(new ActionResourceDefinition(Resources.getInstance().getString("action.button.browse"), "action.button.browse"),
				getActionListener());
	}

	protected JPasswordField getPasswordField() {
		if (null == passwordField)
			createPasswordField();

		return passwordField;
	}

	private void createPasswordField() {
		passwordField = new JPasswordField();
	}

	protected JPasswordField getConfirmField() {
		if (null == confirmField)
			createConfirmField();

		return confirmField;
	}

	private void createConfirmField() {
		confirmField = new JPasswordField();
	}

	protected ActionListener getActionListener() {
		if (null == actionListener)
			createActionListener();

		return actionListener;
	}

	protected Action getOkAction() {
		if (null == okAction)
			createOkAction();

		return okAction;
	}

	private void createOkAction() {
		okAction = new MSBAction(new ActionResourceDefinition(Resources.getInstance().getString("action.button.ok"), "action.button.ok"), getActionListener());
	}

	protected Action getCancelAction() {
		if (null == cancelAction)
			createCancelAction();

		return cancelAction;
	}

	private void createCancelAction() {
		cancelAction = new MSBAction(new ActionResourceDefinition(Resources.getInstance().getString("action.button.cancel"), "action.button.cancel"),
				getActionListener());
	}

	private void createActionListener() {
		actionListener = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				String command = e.getActionCommand();
				assert null != command : "null action command encountered in NewDatabaseDialog"; //$NON-NLS-1$

				if (command.equals("action.button.browse")) //$NON-NLS-1$
					doBrowse();
				else if (command.equals("action.button.ok")) //$NON-NLS-1$
					doOK();
				else if (command.equals("action.button.cancel")) //$NON-NLS-1$
					doCancel();
			}
		};
	}
	
	private void doBrowse() {
		JFileChooser chooser = getFileChooser();
		if (JFileChooser.APPROVE_OPTION == chooser.showOpenDialog(this))
			getLocationField().setText(chooser.getSelectedFile().getAbsolutePath());
	}

	private void doOK() {
		if (arePasswordsDifferent()) {
			JOptionPane.showMessageDialog(this, Resources.getInstance().getString("newdatabasedialog.passwordsdontmatch.message"));
			return;
		}
		
		DataManagerFactory.getInstance().createDataManager(getLocationField().getText(), getPasswordField().getPassword());
		setVisible(false);
	}
	
	private boolean arePasswordsDifferent() {
		return !Arrays.equals(getPasswordField().getPassword(), getConfirmField().getPassword());
	}
	
	private void doCancel() {
		setVisible(false);
	}
	
	private void resetFields() {
		getLocationField().setText(null);
		getPasswordField().setText(null);
		getConfirmField().setText(null);
	}
	
	protected JFileChooser getFileChooser() {
		if (null == fileChooser)
			createFileChooser();
		
		return fileChooser;
	}
	
	private void createFileChooser() {
		fileChooser = new JFileChooser();
		fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		fileChooser.setDialogTitle(Resources.getInstance().getString("newdatabasedialog.browsedirectory.title"));
	}
	
	public void setVisible(boolean value) {
		resetFields();
		
		super.setVisible(value);
	}
}
